package com.zenithmind.mall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.mall.mapper.ProductReviewMapper;
import com.zenithmind.mall.mapper.ProductMapper;
import com.zenithmind.mall.mapper.OrderMapper;
import com.zenithmind.mall.mapper.OrderItemMapper;
import com.zenithmind.mall.pojo.dto.ProductReviewDTO;
import com.zenithmind.mall.pojo.entity.ProductReview;
import com.zenithmind.mall.pojo.entity.Product;
import com.zenithmind.mall.pojo.entity.Order;
import com.zenithmind.mall.pojo.entity.OrderItem;
import com.zenithmind.mall.pojo.query.ProductReviewQuery;
import com.zenithmind.mall.pojo.vo.ProductReviewVO;
import com.zenithmind.mall.pojo.vo.ReviewStatisticsVO;
import com.zenithmind.mall.service.ProductReviewService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商品评价服务实现
 * 
 * @author ZenithMind Team
 * @since 2025-06-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProductReviewServiceImpl extends ServiceImpl<ProductReviewMapper, ProductReview> implements ProductReviewService {

    private final ProductMapper productMapper;
    private final OrderMapper orderMapper;
    private final OrderItemMapper orderItemMapper;

    @Override
    public PageResult<ProductReviewVO> getReviewPage(ProductReviewQuery query) {
        Page<ProductReview> page = new Page<>(query.getCurrent(), query.getSize());
        
        LambdaQueryWrapper<ProductReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductReview::getIsDeleted, 0)
               .eq(StringUtils.hasText(query.getUserId()), ProductReview::getUserId, query.getUserId())
               .eq(StringUtils.hasText(query.getProductId()), ProductReview::getProductId, query.getProductId())
               .eq(StringUtils.hasText(query.getOrderId()), ProductReview::getOrderId, query.getOrderId())
               .eq(query.getRating() != null, ProductReview::getRating, query.getRating())
               .ge(query.getMinRating() != null, ProductReview::getRating, query.getMinRating())
               .le(query.getMaxRating() != null, ProductReview::getRating, query.getMaxRating())
               .eq(query.getIsAnonymous() != null, ProductReview::getIsAnonymous, query.getIsAnonymous())
               .eq(query.getStatus() != null, ProductReview::getStatus, query.getStatus())
               .like(StringUtils.hasText(query.getKeyword()), ProductReview::getContent, query.getKeyword())
               .ge(query.getStartTime() != null, ProductReview::getCreateTime, query.getStartTime())
               .le(query.getEndTime() != null, ProductReview::getCreateTime, query.getEndTime());

        // 处理图片筛选
        if (query.getHasImages() != null) {
            if (query.getHasImages()) {
                wrapper.isNotNull(ProductReview::getImages).ne(ProductReview::getImages, "");
            } else {
                wrapper.and(w -> w.isNull(ProductReview::getImages).or().eq(ProductReview::getImages, ""));
            }
        }

        // 处理商家回复筛选
        if (query.getHasMerchantReply() != null) {
            if (query.getHasMerchantReply()) {
                wrapper.isNotNull(ProductReview::getMerchantReply).ne(ProductReview::getMerchantReply, "");
            } else {
                wrapper.and(w -> w.isNull(ProductReview::getMerchantReply).or().eq(ProductReview::getMerchantReply, ""));
            }
        }

        wrapper.orderByDesc(ProductReview::getCreateTime);

        Page<ProductReview> result = page(page, wrapper);

        // 转换为VO
        List<ProductReviewVO> voList = result.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageResult<>(voList, result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public ProductReviewVO getReviewById(String id) {
        ProductReview review = getById(id);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }
        return convertToVO(review);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createReview(ProductReviewDTO reviewDTO, String userId) {
        // 验证用户是否可以评价
        if (!canUserReview(userId, reviewDTO.getProductId(), reviewDTO.getOrderId())) {
            throw new BusinessException("您无权评价该商品");
        }

        // 检查是否已评价
        LambdaQueryWrapper<ProductReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductReview::getUserId, userId)
               .eq(ProductReview::getOrderItemId, reviewDTO.getOrderItemId())
               .eq(ProductReview::getIsDeleted, 0);
        
        if (count(wrapper) > 0) {
            throw new BusinessException("您已评价过该商品");
        }

        ProductReview review = new ProductReview();
        BeanUtils.copyProperties(reviewDTO, review);
        review.setUserId(userId);
        review.setStatus(0); // 待审核
        review.setLikeCount(0);
        review.setCreateBy(userId);

        // 处理图片列表
        if (reviewDTO.getImages() != null && !reviewDTO.getImages().isEmpty()) {
            review.setImages(String.join(",", reviewDTO.getImages()));
        }

        if (!save(review)) {
            throw new BusinessException("创建评价失败");
        }

        // 更新订单项评价状态
        OrderItem orderItem = orderItemMapper.selectById(reviewDTO.getOrderItemId());
        if (orderItem != null) {
            orderItem.setIsReviewed(1);
            orderItemMapper.updateById(orderItem);
        }

        log.info("创建商品评价成功: {}", review.getId());
        return review.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateReview(String id, ProductReviewDTO reviewDTO, String userId) {
        ProductReview review = getById(id);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }
        
        if (!review.getUserId().equals(userId)) {
            throw new BusinessException("您无权修改该评价");
        }
        
        if (review.getStatus() != 0) {
            throw new BusinessException("只能修改待审核的评价");
        }

        // 更新评价信息
        review.setRating(reviewDTO.getRating());
        review.setContent(reviewDTO.getContent());
        review.setIsAnonymous(reviewDTO.getIsAnonymous());
        review.setUpdateBy(userId);

        // 处理图片列表
        if (reviewDTO.getImages() != null && !reviewDTO.getImages().isEmpty()) {
            review.setImages(String.join(",", reviewDTO.getImages()));
        } else {
            review.setImages(null);
        }

        boolean result = updateById(review);
        if (result) {
            log.info("更新商品评价成功: {}", id);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteReview(String id, String userId) {
        ProductReview review = getById(id);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }
        
        if (!review.getUserId().equals(userId)) {
            throw new BusinessException("您无权删除该评价");
        }

        boolean result = removeById(id);
        if (result) {
            // 更新订单项评价状态
            OrderItem orderItem = orderItemMapper.selectById(review.getOrderItemId());
            if (orderItem != null) {
                orderItem.setIsReviewed(0);
                orderItemMapper.updateById(orderItem);
            }
            log.info("删除商品评价成功: {}", id);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteReviewsBatch(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return true;
        }
        
        // 获取所有评价记录
        List<ProductReview> reviews = listByIds(ids);
        
        boolean result = removeByIds(ids);
        if (result) {
            // 批量更新订单项评价状态
            for (ProductReview review : reviews) {
                OrderItem orderItem = orderItemMapper.selectById(review.getOrderItemId());
                if (orderItem != null) {
                    orderItem.setIsReviewed(0);
                    orderItemMapper.updateById(orderItem);
                }
            }
            log.info("批量删除商品评价成功: {}", ids);
        }
        return result;
    }

    @Override
    public PageResult<ProductReviewVO> getProductReviews(String productId, Integer rating, Integer pageNum, Integer pageSize) {
        Page<ProductReview> page = new Page<>(pageNum, pageSize);
        
        LambdaQueryWrapper<ProductReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductReview::getIsDeleted, 0)
               .eq(ProductReview::getProductId, productId)
               .eq(ProductReview::getStatus, 1) // 只显示已通过审核的评价
               .eq(rating != null, ProductReview::getRating, rating)
               .orderByDesc(ProductReview::getCreateTime);

        Page<ProductReview> result = page(page, wrapper);

        // 转换为VO
        List<ProductReviewVO> voList = result.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageResult<>(voList, result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public PageResult<ProductReviewVO> getUserReviews(String userId, Integer pageNum, Integer pageSize) {
        Page<ProductReview> page = new Page<>(pageNum, pageSize);
        
        LambdaQueryWrapper<ProductReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductReview::getIsDeleted, 0)
               .eq(ProductReview::getUserId, userId)
               .orderByDesc(ProductReview::getCreateTime);

        Page<ProductReview> result = page(page, wrapper);

        // 转换为VO
        List<ProductReviewVO> voList = result.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageResult<>(voList, result.getTotal(), result.getCurrent(), result.getSize());
    }

    /**
     * 转换为VO
     */
    private ProductReviewVO convertToVO(ProductReview review) {
        ProductReviewVO vo = new ProductReviewVO();
        BeanUtils.copyProperties(review, vo);

        // 处理图片列表
        if (StringUtils.hasText(review.getImages())) {
            vo.setImages(List.of(review.getImages().split(",")));
        }

        // 获取商品信息
        Product product = productMapper.selectById(review.getProductId());
        if (product != null) {
            vo.setProductName(product.getName());
            vo.setProductImage(product.getMainImage());
        }

        // 设置状态文本
        vo.setStatusText(getStatusText(review.getStatus()));

        return vo;
    }

    /**
     * 获取状态文本
     */
    private String getStatusText(Integer status) {
        if (status == null) return "未知";
        return switch (status) {
            case 0 -> "待审核";
            case 1 -> "已通过";
            case 2 -> "已拒绝";
            default -> "未知";
        };
    }

    @Override
    public ReviewStatisticsVO getReviewStatistics(String productId) {
        LambdaQueryWrapper<ProductReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductReview::getIsDeleted, 0)
               .eq(ProductReview::getProductId, productId)
               .eq(ProductReview::getStatus, 1); // 只统计已通过审核的评价

        List<ProductReview> reviews = list(wrapper);

        ReviewStatisticsVO statistics = new ReviewStatisticsVO();
        statistics.setProductId(productId);
        statistics.setTotalCount((long) reviews.size());

        if (reviews.isEmpty()) {
            statistics.setAverageRating(BigDecimal.ZERO);
            statistics.setPositiveRate(BigDecimal.ZERO);
            statistics.setRatingCounts(new ArrayList<>());
            statistics.setImageReviewCount(0L);
            return statistics;
        }

        // 计算各星级数量
        long fiveStarCount = 0, fourStarCount = 0, threeStarCount = 0, twoStarCount = 0, oneStarCount = 0;
        int totalRating = 0;
        long imageReviewCount = 0;

        for (ProductReview review : reviews) {
            totalRating += review.getRating();
            switch (review.getRating()) {
                case 5 -> fiveStarCount++;
                case 4 -> fourStarCount++;
                case 3 -> threeStarCount++;
                case 2 -> twoStarCount++;
                case 1 -> oneStarCount++;
            }

            // 统计有图评价
            if (StringUtils.hasText(review.getImages())) {
                imageReviewCount++;
            }
        }

        // 计算平均评分
        BigDecimal averageRating = BigDecimal.valueOf((double) totalRating / reviews.size())
                .setScale(2, RoundingMode.HALF_UP);
        statistics.setAverageRating(averageRating);

        // 计算好评率（4-5星的比例）
        BigDecimal positiveRate = BigDecimal.valueOf((double) (fiveStarCount + fourStarCount) / reviews.size() * 100)
                .setScale(2, RoundingMode.HALF_UP);
        statistics.setPositiveRate(positiveRate);

        // 设置各星级统计
        List<ReviewStatisticsVO.RatingCount> ratingCounts = new ArrayList<>();
        ratingCounts.add(new ReviewStatisticsVO.RatingCount(5, fiveStarCount,
                BigDecimal.valueOf((double) fiveStarCount / reviews.size() * 100).setScale(2, RoundingMode.HALF_UP)));
        ratingCounts.add(new ReviewStatisticsVO.RatingCount(4, fourStarCount,
                BigDecimal.valueOf((double) fourStarCount / reviews.size() * 100).setScale(2, RoundingMode.HALF_UP)));
        ratingCounts.add(new ReviewStatisticsVO.RatingCount(3, threeStarCount,
                BigDecimal.valueOf((double) threeStarCount / reviews.size() * 100).setScale(2, RoundingMode.HALF_UP)));
        ratingCounts.add(new ReviewStatisticsVO.RatingCount(2, twoStarCount,
                BigDecimal.valueOf((double) twoStarCount / reviews.size() * 100).setScale(2, RoundingMode.HALF_UP)));
        ratingCounts.add(new ReviewStatisticsVO.RatingCount(1, oneStarCount,
                BigDecimal.valueOf((double) oneStarCount / reviews.size() * 100).setScale(2, RoundingMode.HALF_UP)));

        statistics.setRatingCounts(ratingCounts);
        statistics.setImageReviewCount(imageReviewCount);

        // 获取最新评价（前3条）
        LambdaQueryWrapper<ProductReview> latestWrapper = new LambdaQueryWrapper<>();
        latestWrapper.eq(ProductReview::getIsDeleted, 0)
                    .eq(ProductReview::getProductId, productId)
                    .eq(ProductReview::getStatus, 1)
                    .orderByDesc(ProductReview::getCreateTime)
                    .last("LIMIT 3");
        List<ProductReview> latestReviews = list(latestWrapper);
        statistics.setLatestReviews(latestReviews.stream().map(this::convertToVO).collect(Collectors.toList()));

        // 获取热门评价（前3条）
        statistics.setHotReviews(getHotReviews(productId, 3));

        return statistics;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean likeReview(String reviewId, String userId) {
        ProductReview review = getById(reviewId);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }

        // 增加点赞数
        LambdaUpdateWrapper<ProductReview> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ProductReview::getId, reviewId)
               .setSql("like_count = like_count + 1");

        boolean result = update(wrapper);
        if (result) {
            log.info("用户 {} 点赞评价成功: {}", userId, reviewId);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean unlikeReview(String reviewId, String userId) {
        ProductReview review = getById(reviewId);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }

        // 减少点赞数
        LambdaUpdateWrapper<ProductReview> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ProductReview::getId, reviewId)
               .setSql("like_count = GREATEST(like_count - 1, 0)");

        boolean result = update(wrapper);
        if (result) {
            log.info("用户 {} 取消点赞评价成功: {}", userId, reviewId);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean replyReview(String reviewId, String replyContent, String userId) {
        ProductReview review = getById(reviewId);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }

        review.setMerchantReply(replyContent);
        review.setMerchantReplyTime(LocalDateTime.now());
        review.setUpdateBy(userId);

        boolean result = updateById(review);
        if (result) {
            log.info("商家回复评价成功: {}", reviewId);
        }
        return result;
    }

    @Override
    public Boolean canUserReview(String userId, String productId, String orderId) {
        // 检查订单是否存在且属于用户
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(Order::getId, orderId)
                   .eq(Order::getUserId, userId)
                   .eq(Order::getIsDeleted, 0);

        Order order = orderMapper.selectOne(orderWrapper);
        if (order == null) {
            return false;
        }

        // 检查订单状态是否为已完成
        if (order.getStatus() != 4) { // 假设4表示已完成
            return false;
        }

        // 检查订单中是否包含该商品
        LambdaQueryWrapper<OrderItem> itemWrapper = new LambdaQueryWrapper<>();
        itemWrapper.eq(OrderItem::getOrderId, orderId)
                   .eq(OrderItem::getProductId, productId)
                   .eq(OrderItem::getIsDeleted, 0);

        return orderItemMapper.selectCount(itemWrapper) > 0;
    }

    @Override
    public List<ProductReviewVO> getHotReviews(String productId, Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }

        LambdaQueryWrapper<ProductReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductReview::getIsDeleted, 0)
               .eq(ProductReview::getProductId, productId)
               .eq(ProductReview::getStatus, 1) // 只显示已通过审核的评价
               .orderByDesc(ProductReview::getLikeCount)
               .orderByDesc(ProductReview::getCreateTime)
               .last("LIMIT " + limit);

        List<ProductReview> reviews = list(wrapper);
        return reviews.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean auditReview(String id, Integer status, String auditRemark) {
        ProductReview review = getById(id);
        if (review == null) {
            throw new BusinessException("评价不存在");
        }

        review.setStatus(status);
        review.setUpdateBy(UserContext.getUserId());

        boolean result = updateById(review);
        if (result) {
            log.info("审核评价成功: {} -> {}", id, status);
        }
        return result;
    }

    @Override
    public Long getPendingAuditCount() {
        LambdaQueryWrapper<ProductReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductReview::getIsDeleted, 0)
               .eq(ProductReview::getStatus, 0); // 待审核状态

        return count(wrapper);
    }
}
